package main

import (
	"bytes"
	"fmt"
	"net/http"
	"os"

	"golang.org/x/net/html"
)

func forEachNode(n *html.Node, pre, post func(n *html.Node)) {
	if pre != nil {
		pre(n)
	}
	for c := n.FirstChild; c != nil; c = c.NextSibling {
		forEachNode(c, pre, post)
	}

	if post != nil {
		post(n)
	}
}

func main() {
	resp, err := http.Get(os.Args[1])
	if err != nil {
		return
	}
	doc, err := html.Parse(resp.Body)
	resp.Body.Close()
	if err != nil {
		fmt.Fprintf(os.Stderr, "outline: %v\n", err)
		os.Exit(1)
	}
	var depth int
	var startElement, endElement func(n *html.Node)
	startElement = func(n *html.Node) {
		if n.Type == html.ElementNode {
			var s bytes.Buffer
			for _, a := range n.Attr {
				fmt.Fprintf(&s, "%s=\"%s\" ", a.Key, a.Val)
			}
			if c := n.FirstChild; c == nil {
				s.WriteByte('/')
			}
			fmt.Printf("%*s<%s %s>\n", depth*2, "", n.Data, s.String())
			depth++
		}
		if n.Type == html.TextNode {
			fmt.Printf("%*s\n", depth*2, n.Data)
			depth++
		}
		if n.Type == html.CommentNode {
			fmt.Printf("%*s\n", depth*2, n.Data)
			depth++
		}
	}

	endElement = func(n *html.Node) {
		if n.Type == html.ElementNode || n.Type == html.TextNode || n.Type == html.CommentNode {
			depth--
			if c := n.FirstChild; c != nil {
				fmt.Printf("%*s</%s>\n", depth*2, "", n.Data)
			}
		}
	}
	forEachNode(doc, startElement, endElement)
}
